/*
 * Copyright (c) 2006-2021, Halo team
 *
 * SPDX-License-Identifier: GPLv3
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-09-11     Eywen        the first version
 */
#ifndef DRV_SMART_PWM_H_
#define DRV_SMART_PWM_H_

#include "common.h"

#define SMART_STEP_TASK_BUFF_LEN    (4UL)


/* 驱动支持的pwm通道个数, 用来绑定驱动结构体 */
typedef enum {
    smart_step_0 = 0,
    smart_step_1,
    smart_step_2,
    smart_step_3,
    smart_step_max
}smart_step_id_t;

typedef struct smart_step_task_t{         /* pwm任务 */
    float freq;                           /* pwm的频率 */
    uint32_t pulse;                       /* pwm的数量 */
}smart_step_task_t;

typedef struct smart_step_cnt{            /* pwm计时器 */
    uint32_t cnt;                         /* 临时计数器 */
    uint32_t reload;                      /* 重载值 */
}smart_step_cnt_t;

typedef enum{                             /* 步进电机运行状态 */
    smart_step_st_running,                /* 步进电机运行状态 */
    smart_step_st_paused,                 /* 步进电机暂停状态 */
    smart_step_st_idle,                   /* 步进电机空闲状态，表示task队列已经为空 */
}smart_step_status_t;

typedef enum{
    smart_step_rotation_forward,
    smart_step_rotation_reverse,
}smart_step_rotation_t;

typedef struct smart_step_t smart_step_t;
typedef struct _smart_step_ops_t smart_step_ops_t;

typedef struct smart_step_t
{
    smart_step_id_t id;                 /* pwm通道唯一标识 */
    int pin_pwm;                        /* pwm引脚 */
    int pin_dir;                        /* 电机方向引脚 */
    int pin_en;                         /* 电机使能引脚 */
    bool forward_rotation_level;        /* 正向转动电平 */
    bool enable_level;                  /* 使能电平 */
    smart_step_ops_t *ops;              /* pwm操作接口 */
    ringbuff_t *pulse_list;             /* pwm脉冲任务队列 */
    smart_step_status_t status;         /* pwm当前状态 */
    smart_step_task_t cur_task;         /* 当前任务 */
    smart_step_cnt_t counter;           /* 定时器计数器 */
    uint32_t timer_freq;                /* 定时器触发频率 */

    int32_t cur_pulse_loc;             /* 记录电机转动的脉冲位置,用来获得当前位置 */
}smart_step_t;

typedef struct _smart_step_ops_t
{
    bool  (*init) (smart_step_t *device, int pin_pwm, int pin_en, int pin_dir,
                   uint32_t timer_freq,  smart_step_id_t id);
    void  (*pause)(smart_step_t *device);
    void  (*clear)(smart_step_t *device);
    void  (*start)(smart_step_t *device);
    void  (*timer_schdule)(smart_step_t *device);
    bool  (*add_task)(smart_step_t *device, smart_step_task_t *task);
    bool  (*task_is_full)(smart_step_t *device);
    bool  (*task_is_empty)(smart_step_t *device);
    void  (*enable)(smart_step_t *device, bool en);
    void  (*release)(smart_step_t *device);
    uint32_t (*pulse)(smart_step_t *device);
    void (*forward_level_set)(smart_step_t *device, bool level);
    void (*reset_cur_pulse_loc)(smart_step_t *device);
    smart_step_status_t (*status)(smart_step_t *device);
    bool (*is_motion)(smart_step_t *step);
}smart_step_ops_t;

smart_step_t *smart_step_find_by_id(smart_step_id_t id);
bool smart_step_register(smart_step_t *smart_step);

#endif /* APPLICATIONS_DRIVER_DRV_STEP_H_ */
